﻿using AutoMapper;
using HikRcsService._631_Optical;
using HikRcsService.Common;
using Newtonsoft.Json;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Ocsp;
using Quartz;
using Serilog;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using WCS_Core_Configuration;
using WCS_Entity.Dto.TaskDto;
using WCS_Quartz_Task;
using WCS_Quartz_Task._631;
using WCS_Service.DomianService;
using WCS_Service.DomianService.Interface;
using WCS_Service.DomianService.Models;
using WCS_Service.Enums;
using WCS_Service.Interface;
using WCS_Service.Models;
using WCS_Service.Models.SerialNetModel;
using WCS_Utility.ConstString;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
using static StackExchange.Redis.Role;

namespace WCS_Service
{
    /// <summary>
    /// 631项目WCS项目主控
    /// </summary>
    public class WCSMainControlManage_631 : WCSMainControlManage
    {
        #region 属性
        /// <summary>
        /// 等待任务开始中的批任务
        /// </summary>
        private ConcurrentDictionary<string, WaitBatchTaskModel> waitStartCTUTasks = new();

        private readonly IQuartzJobProcess _quartzJobProcess;
        private OpticalFunCodeApiMap opticalFunCodeApiMap = new OpticalFunCodeApiMap();

        private IRcsOvertimeDomainService _rcsOvertimeDomainService;
        private ICommonResDomainService _commonResDomainService;

        private RollerParaModel rollerParaModel = new();
        #endregion

        public WCSMainControlManage_631(IAutoEquipmentService autoEquipmentService, 
            IAutoEquipmentOperateService autoEquipmentOperateService,
            IComControl comControl, IMapper mapper, 
            ISendMsgToSubService sendMsgToSubService, 
            IOpticalDomainService opticalDomainService, 
            IAGVDomainService agvDomainService, 
            IRCSDomainService rcsDomainService,
            IQuartzJobProcess quartzJobProcess,
            IMsgAbnormalService msgAbnormalService,
            ITaskService taskService,
            IUpperSysDomainService upperSysDomainService,
            IRcsOvertimeDomainService rcsOvertimeDomainService,
            ILineDomainService lineDomainService,
            IMapPositionService mapPositionService,
            ICommonResDomainService commonResDomainService) : base(autoEquipmentService, 
                autoEquipmentOperateService, comControl, mapper, 
                sendMsgToSubService, opticalDomainService, 
                agvDomainService, rcsDomainService, msgAbnormalService, taskService, 
                upperSysDomainService, lineDomainService, mapPositionService)
        {
            _quartzJobProcess = quartzJobProcess;
            _rcsOvertimeDomainService = rcsOvertimeDomainService;
            _commonResDomainService = commonResDomainService;
        }
        public override async Task ComonTest()
        {
            var ss = _rcsOvertimeDomainService.WaitResultQueue;

            var c2 = _commonResDomainService.QueryCommonRoadwayStateAsync();
            var c1 = _commonResDomainService.GetCommonRoadway();
            var c3 = _commonResDomainService.RoadwayStateUpdateAsync("r1",true);
            var c4 = _commonResDomainService.ReleaseCommonRoadwayAsync();
            var c5 = _commonResDomainService.ReleaseRoadwayAsync("r1");
            var c6 = _commonResDomainService.ReleaseWaitCommonRoadwayAsync();
            var c7 = _commonResDomainService.AddWaitCommonRoadwayQueueAsync("1004","4847");
            var c8 = _commonResDomainService.GetRaodWayStateAsync("r1");
        }
        public override async Task Test()
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();

            creatTaskModel.taskTyp = "631TEST";
            //creatTaskModel.taskCode = ;
            //第一个移动点 当前巷道出口位置等待点
            positionInfo firstPoint = new positionInfo();
            firstPoint.positionCode = "102000AA098000";
            firstPoint.type = HikRcsConst.LocationCode;

            positionInfo secPoint = new positionInfo();
            secPoint.positionCode = "105000AA100000";
            secPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(firstPoint);
            positionInfos.Add(secPoint);
            creatTaskModel.positionCodePath = positionInfos;
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync("1004");
            await DistributeInfoAsync(opticalInfo, ConstStringData.CreatTask_WCSApi, creatTaskModel, false);
        }

        protected override async Task CustomInitAsync()
        {
            await RcsOverTimeJob();
            await TaskScanJob();
            await RollerDefaultPara();
            _opticalDomainService.OppsiteBuidChange += OpticalOppsiteProcess;
            _opticalDomainService.OppsiteDisConChange += _agvDomainService.AgvEqCodeUpdate;

            _rcsDomainService.AgvInfoChange += AgvInfoUpdateAsync;
            _rcsDomainService.TaskInfoChange += TaskInfoUpdateAsync;
            _rcsDomainService.MapInfoChange += MapInfoUpdateAsync;
            _rcsDomainService.PodBerthAndMatChange += PodBerthAndMatAsync;
            _rcsDomainService.ResultChange += ResultAsync;
            _rcsDomainService.ResultDataChange += ResultDataAsync;
            _rcsDomainService.EnterComRoadWayChange += EnterCommonRoadwayManageAsync;
            _rcsDomainService.ExitComRoadWayChange += LeaveCommonRoadwayManageAsync;
            _rcsDomainService.TaskEndChange += TaskEndAsync;
            _rcsDomainService.ChargeReportChange += ChargeReportAsync;
            _rcsDomainService.TaskPauseChange += TaskPauseAsync;
            _rcsDomainService.RollerInfoChange += _agvDomainService.UpdateAgvPeripheralAsync;
            _rcsDomainService.WarnInfoChange += WarnProcessAsync;

            _agvDomainService.agvArriveCharge += _commonResDomainService.ReleaseCommonRoadwayAsync;
            _agvDomainService.agvOverTimeChange += AgvOverTimeAsync;
            _agvDomainService.agvContinueChange += AgvContinueAsync;
            _agvDomainService.agvAbnormalChange += AgvAbnormalAsync;

            _rcsOvertimeDomainService.OvertimeCreatTaskChange += CreatTaskOvertimeAsync;
        }

        private async Task RollerDefaultPara()
        {
            await Task.Run(() => 
            {
                if (ushort.TryParse(AppSettingsConstVars.Speed, out ushort speed))
                {
                    rollerParaModel.Speed = speed;
                }
                if (ushort.TryParse(AppSettingsConstVars.Ass, out ushort ass))
                {
                    rollerParaModel.Ass = ass;
                }
                if (ushort.TryParse(AppSettingsConstVars.Dec, out ushort dec))
                {
                    rollerParaModel.Dec = dec;
                }
                if (ushort.TryParse(AppSettingsConstVars.LoadTime, out ushort loadTime))
                {
                    rollerParaModel.LoadTime = loadTime;
                }
                if (ushort.TryParse(AppSettingsConstVars.UnloadTime, out ushort unloadTime))
                {
                    rollerParaModel.UnloadTime = unloadTime;
                }
            });
        }

        #region 定时任务
        private async Task RcsOverTimeJob()
        {
            var jobDetail = JobBuilder.Create<OverTimeJob>().WithIdentity(ConstStringData.RcsOverTimeCheck,
                   ConstStringData.RcsOverTimeCheck).Build();
            jobDetail.JobDataMap.Put("overTime", _rcsOvertimeDomainService.OverTimeCheck);
            var trigger = TriggerBuilder.Create()
                                        .WithSimpleSchedule(m =>
                                        {
                                            m.WithIntervalInSeconds(10).RepeatForever();
                                        })
                                        .Build();

            //添加超时间检查
            await _quartzJobProcess.AddJobAsync(jobDetail, trigger);
        }
        /// <summary>
        /// 任务扫描
        /// </summary>
        /// <returns></returns>
        private async Task TaskScanJob()
        {
            var jobDetail = JobBuilder.Create<TaskScanJob>().WithIdentity(ConstStringData.TaskScan,
                  ConstStringData.TaskScan).Build();
            jobDetail.JobDataMap.Put("taskScan", TaskScanProcessAsync);
            var trigger = TriggerBuilder.Create()
                                        .WithSimpleSchedule(m =>
                                        {
                                            m.WithIntervalInSeconds(5).RepeatForever();
                                        })
                                        .Build();

            //添加扫描未执行任务
            await _quartzJobProcess.AddJobAsync(jobDetail, trigger);
        }
        #endregion

        private async Task TaskScanProcessAsync()
        {
            CTUTaskScanProcess();
            await TaskTransportScanProcess();
        }

        /// <summary>
        /// 潜伏搬运任务扫描
        /// </summary>
        /// <returns></returns>
        private async Task TaskTransportScanProcess()
        {
            var tasks = await _taskService.QueryWaitTaskBaseAreaCode(AppSettingsConstVars.Area_2);
            if (tasks is null)
            {
                return;
            }
            //查询休息点位是否有等待任务的AGV
            var availableOptical = await _opticalDomainService.QueryOpticalBaseTypeAsync(OpticalType.Rest, AppSettingsConstVars.Area_2);
            //休息点没有车
            if (availableOptical is null)
            {
                return;
            }

            var processTasks = tasks.OrderBy(t => t.createTime).Take(availableOptical.Count)?.ToList();
            if (processTasks is null)
            {
                return;
            }
            List<Task> addTask = new();
            foreach (var item in processTasks)
            {
                addTask.Add(RollerTaskProcessAsync(item));
            }
            await Task.WhenAll(addTask);
        }
        private async Task CTUTaskScanProcess()
        {
            var waitTask = await _taskService.QueryWaitTaskBaseAreaCode(AppSettingsConstVars.Area_2);
            if (waitTask is null)
            {
                return;
            }
            //把同一个巷道的任务分在一组
            var groupTaskInfo = waitTask.GroupBy(t => t.targetRoadWay)?.ToList();
            if (groupTaskInfo is null || !groupTaskInfo.Any())
            {
                return;
            }
            List<Task> addBatch = new();
            foreach (var taskInfo in groupTaskInfo)
            {
                addBatch.Add(TaskBatchAnalysisAsync(taskInfo.ToList(), taskInfo.Key));
            }
            await Task.WhenAll(addBatch);
        }
        #region private
        /// <summary>
        /// 滚筒任务处理
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        private async Task RollerTaskProcessAsync(TaskDto task)
        {
            if (task is null)
            {
                return;
            }
            //查询休息点位是否有等待任务的AGV
            var availableOptical = (await _opticalDomainService.QueryOpticalBaseTypeAsync(OpticalType.Rest, AppSettingsConstVars.Area_2))?.Where(o => !o.isLock).FirstOrDefault();
            //休息点没有车
            if (availableOptical is null)
            {
                return;
            }
            var flag = await _opticalDomainService.LockChargeOpticalChangeAsync(availableOptical.id, true);
            if (!flag)
            {
                Log.Error($"休息中AGV锁定失败！");
                return;
            }
            var agvInfo = await _agvDomainService.QueryAgvInfoBaseEqCodeAsync(availableOptical.id.ToString());
            if (agvInfo is null)
            {
                Log.Error($"{availableOptical.id}光通信位置的AGV信息获取失败！");
                var unlockFlag = await _opticalDomainService.LockChargeOpticalChangeAsync(availableOptical.id, false);
                return;
            }
            OpticalTaskModel opticalTaskModel = new();
            opticalTaskModel.sendTaskOptical = availableOptical;
            opticalTaskModel.agvId = agvInfo.agvCode;

            await TaskAnalysisAsync(task,opticalTaskModel);
        }
        /// <summary>
        /// 任务批量分析--按照任务所属巷道-CTU任务
        /// </summary>
        /// <returns></returns>
        private async Task TaskBatchAnalysisAsync(List<TaskDto> tasks,string roadWayCode)
        {
            if (tasks is null || !tasks.Any())
            {
                return;
            }
            //获取指定巷道的状态
            var model = await _commonResDomainService.GetRaodWayStateAsync(roadWayCode);
            if (model is null)
            {
                Log.Error($"目标巷道{roadWayCode}不存在!");
                List<Task<bool>> addErr = new List<Task<bool>>();
                foreach (var task in tasks)
                {
                    addErr.Add(BatchUpdateTaskState(task, TaskState.Err, $"目标巷道{task.targetRoadWay}不存在!")); 
                }
                await Task.WhenAll(addErr);
                return;
            }
            //任务巷道占用中
            if (model.isOccupation)
            {
                List<Task<bool>> addErr = new List<Task<bool>>();
                foreach (var task in tasks)
                {
                    addErr.Add(BatchUpdateTaskState(task, TaskState.wait, ""));
                }
                return;
            }
            var opticalInfo = await GetAvailableAgvAsync(model);

            if (opticalInfo.sendTaskOptical is null || string.IsNullOrEmpty(opticalInfo.agvId))
            {
                List<Task<bool>> addErr = new List<Task<bool>>();
                foreach (var task in tasks)
                {
                    addErr.Add(BatchUpdateTaskState(task, TaskState.wait, ""));
                }
                return;
            }
            //任务巷道占用
            await _commonResDomainService.RoadwayStateUpdateAsync(roadWayCode, true);

            var inTasks = tasks.Where(t => t.taskType == AppSettingsConstVars.WarehousingTaskName).OrderBy(t => t.createTime).Take(4);
            var outTasks = tasks.Where(t => t.taskType == AppSettingsConstVars.OutboundTaskName).OrderBy(t => t.createTime).Take(4);

            List<TaskDto> analysisTask = new();
            if (inTasks is not null && inTasks.Any())
            {
                analysisTask.AddRange(inTasks);
            }
            if (outTasks is not null && outTasks.Any())
            {
                analysisTask.AddRange(outTasks);
            }
            var batchNum = GetreqCode();
            List<Task> taskAnalysisModels = new();
            foreach (var task in analysisTask)
            {
                //将该任务添加到等待执行队列中
                await AddWaitStartBatchTaskAsync(batchNum, task.id.ToString(), (analysisTask.IndexOf(task) + 1).ToString());
            }
            foreach (var task in analysisTask) 
            {
                taskAnalysisModels.Add(TaskAnakysisProcessAsync(task, opticalInfo, batchNum, analysisTask.IndexOf(task)+1));
            }
            await Task.WhenAll(taskAnalysisModels);
            
            //下发移动许可
            //await SendContinueTaskAsync(opticalInfo.sendTaskOptical);
        }
        /// <summary>
        /// 任务分析处理
        /// </summary>
        /// <returns></returns>
        private async Task TaskAnakysisProcessAsync(TaskDto task, OpticalTaskModel opticalInfo,string batchNum,int seq)
        {
            var updateStates = await TaskAnalysisAsync(task, opticalInfo);
            if (updateStates is not null)
            {
                updateStates.batchNumber = batchNum;
                updateStates.batchSeq = seq.ToString();
                var flag = await UpdateTaskStateAsync(updateStates);
                if (!flag)
                {
                    Log.Error($"任务{updateStates.taskId}状态更新失败");
                }
            }
        }
        /// <summary>
        /// 任务分析
        /// </summary>
        /// <param name="task"></param>
        /// <returns></returns>
        private async Task<TaskAnalysisModel> TaskAnalysisAsync(TaskDto task,OpticalTaskModel opticalInfo)
        {
            try
            {
                TaskAnalysisModel result = new();

                result.orderId = task.orderCode;
                result.taskId = task.id;

                //获取任务模板编号
                var templateCode = GetTaskTemplateCode(task.taskType, opticalInfo.transferRoadway);
                if (string.IsNullOrEmpty(templateCode))
                {
                    result.taskState = TaskState.Err;
                    result.errMsg = $"任务类型未知{task.taskType}";
                    return result;
                }

                //transferRoadway true是需要从别的巷道调车，false执行任务的AGV就在当前巷道待命点
                CreatTaskModel creatTaskModel = new CreatTaskModel();
                creatTaskModel = await CreatTaskParaProcessAsync(task, opticalInfo, templateCode);
                if (creatTaskModel == null) 
                {
                    result.taskState = TaskState.Err;
                    result.errMsg = $"任务目标储位在地图点位中未绑定";
                    return result;
                }
                await DistributeInfoAsync(opticalInfo.sendTaskOptical, ConstStringData.CreatTask_WCSApi, task, false);
                result.taskState = TaskState.executing;
                return result;
            }
            catch (Exception ex) 
            {
                TaskAnalysisModel result = new();
                result.taskId = task.id;
                result.taskState = TaskState.Err;
                result.errMsg = ex.Message;
                return result;
            }
        }

        /// <summary>
        /// 入库任务下发点获取
        /// </summary>
        /// <param name="roadwayCode"></param>
        /// <returns></returns>
        private async Task<OpticalTaskModel> GetAvailableAgvAsync(RoadWayModel model)
        {
            OpticalTaskModel result = new();
            //查询指定巷道的待命点是否建立和AGV的通信
            var opticalInfo = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.Standby, model.code,AppSettingsConstVars.Area_2);
            if (opticalInfo is null)
            {
                return result;
            }
            ManageAgvModel availableAgvInfo = null;
            if (opticalInfo.available)
            {
                //在该光通信模块处的AGV信息
                availableAgvInfo = await _agvDomainService.QueryAgvInfoBaseEqCodeAsync(opticalInfo.id.ToString());
            }
            //大箱子
            if (model.type == RoadWayType.maxBox)
            {
                if (!opticalInfo.available)
                {
                    return result;
                }
                if (availableAgvInfo is null || !await BatteryCompareAsync(availableAgvInfo.battery) || availableAgvInfo.stateAbnormal)
                {
                    return result;
                }
                result.sendTaskOptical = opticalInfo;
                result.transferRoadway = false;
                result.agvId = availableAgvInfo.agvCode;
                return result;
            }
            //任务巷道等待点没有AGV
            if (!opticalInfo.available)
            {
                return await GetBestOpsiteAsync(opticalInfo, model.index);
            }
            if (availableAgvInfo is null || !await BatteryCompareAsync(availableAgvInfo.battery) || availableAgvInfo.stateAbnormal)
            {
                return result;
            }
            result.transferRoadway = false;
            result.sendTaskOptical = opticalInfo;
            result.agvId = availableAgvInfo.agvCode;
            return result;
        }
        /// <summary>
        /// 比较当前电量和最低工作电量
        /// </summary>
        /// <param name="battery"></param>
        /// <returns></returns>
        private async Task<bool> BatteryCompareAsync(string battery)
        {
            return await Task.Run(() => 
            {
                if (int.TryParse(battery, out int value1) && int.TryParse(AppSettingsConstVars.ChargeBattery, out int value2))
                {
                    if (value1 < value2)
                    {
                        return false;
                    }
                }
                return true;
            });
           
        }
        /// <summary>
        /// 充电时当前电量大于最低可以工作电量返回True
        /// </summary>
        /// <param name="battery"></param>
        /// <returns></returns>
        private bool BatteryCompareWork(string battery)
        {
           if (int.TryParse(battery, out int value1) && int.TryParse(AppSettingsConstVars.LowWorkBattery, out int value2))
            {
                if (value1 > value2)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 根据巷道号查询最合适的待命点
        /// </summary>
        /// <param name="infos"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task<OpticalTaskModel> GetBestOpsiteAsync(RunEqInfoModel<OpticalCustomInfoModel> taskOptical,int index)
        {
            OpticalTaskModel result = new();
            int diff = 8;
            RunEqInfoModel<OpticalCustomInfoModel> midCheck = null;
            string agvId = "";
            var chargeCtrInfo = (await _opticalDomainService.QueryOpticalBaseTypeAsync(OpticalType.ChargeControl, AppSettingsConstVars.Area_2))?.FirstOrDefault();
            //优先充电控制点有车调用
            if (chargeCtrInfo is not null)
            {
                var agvCode = await AvailableAgvInfoCheck(chargeCtrInfo.id.ToString());
                if (agvCode is not null)
                {
                    result.transferRoadway = true;
                    //var flag = await _commonResDomainService.QueryCommonRoadwayStateAsync();
                    result.agvId = agvId;
                    result.sendTaskOptical = chargeCtrInfo;
                    result.ctrTaskOptical = chargeCtrInfo;
                    result.ctr1TaskOptical = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.Control, taskOptical.customInfo.roadwayCode, AppSettingsConstVars.Area_2);
                    result.endTaskOptical = taskOptical;
                    return result;
                }
            }
            //查询所有等待点空闲的AGV
            var sitInfos = await _opticalDomainService.QueryOpticalBaseTypeAsync(OpticalType.Standby, AppSettingsConstVars.Area_2);
            if (sitInfos is not null && sitInfos.Any())
            {
                foreach (var item in sitInfos)
                {
                    //获取指定巷道的状态
                    var roadWayModel = await _commonResDomainService.GetRaodWayStateAsync(item.customInfo.roadwayCode);
                    if (roadWayModel is not null &&
                        roadWayModel.type != RoadWayType.maxBox && !roadWayModel.isOccupation)
                    {
                        var agvInfo = await _agvDomainService.QueryAgvInfoBaseEqCodeAsync(taskOptical.id.ToString());
                        if (agvInfo is null || !await BatteryCompareAsync(agvInfo.battery))
                        {
                            break;
                        }
                        var newdiff = Math.Abs(roadWayModel.index - index);
                        if (newdiff == 1)
                        {
                            agvId = agvInfo.agvCode.ToString();
                            midCheck = item;
                            break;
                        }
                        if (newdiff < diff)
                        {
                            agvId = agvInfo.agvCode.ToString();
                            diff = newdiff;
                            midCheck = item;
                        }
                    }
                }
                result.transferRoadway = true;
                result.sendTaskOptical = midCheck;
                if (midCheck is not null)
                {
                    //锁定AGV当前所在巷道
                    await _commonResDomainService.RoadwayStateUpdateAsync(midCheck.customInfo.roadwayCode, true);
                    result.agvId = agvId;
                    result.ctrTaskOptical = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.Control, 
                        midCheck?.customInfo.roadwayCode,AppSettingsConstVars.Area_2);
                    result.ctr1TaskOptical = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.Control, 
                            taskOptical.customInfo.roadwayCode, AppSettingsConstVars.Area_2);
                    result.endTaskOptical = taskOptical;
                }

                return result;
            }
            var chargeInfo = (await _opticalDomainService.QueryOpticalBaseTypeAsync(OpticalType.Charge, AppSettingsConstVars.Area_2))?.FirstOrDefault();
            //充电点有车
            if (chargeInfo is not null)
            {
                //判断当前车充电量
                var agvInfo = await _agvDomainService.QueryAgvInfoBaseEqCodeAsync(chargeInfo.id.ToString());
                if (agvInfo is not null && BatteryCompareWork(agvInfo.battery))
                {
                    result.transferRoadway = true;
                    //var flag = await _commonResDomainService.QueryCommonRoadwayStateAsync();
                    result.agvId = agvId;
                    result.sendTaskOptical = chargeInfo;
                    result.ctrTaskOptical = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.ChargeControl,
                                        _commonResDomainService.GetCommonRoadway(), AppSettingsConstVars.Area_2);
                    result.ctr1TaskOptical = await _opticalDomainService.QueryAwqBaseRoadwayCodeAsync(OpticalType.Control, 
                                               taskOptical.customInfo.roadwayCode, AppSettingsConstVars.Area_2);
                    result.endTaskOptical = taskOptical;
                    return result;
                }
            }
            return result;
        }
        /// <summary>
        /// 判断预备执行任务的AGV是否满足条件
        /// </summary>
        /// <returns></returns>
        private async Task<ManageAgvModel> AvailableAgvInfoCheck(string opticalId)
        {
            if (opticalId is null)
            {
                return null;
            }
            var agvInfo = await _agvDomainService.QueryAgvInfoBaseEqCodeAsync(opticalId);
            if (agvInfo is null)
            {
                return null;
            }
            if (!await BatteryCompareAsync(agvInfo.battery) || agvInfo.stateAbnormal || agvInfo.status != AgvStates.Idletask)
            {
                Log.Information($"AGV{agvInfo.agvCode}电量低或异常状态或不是任务空闲状态");
                return null;
            }
            return agvInfo;       
        }


        /// <summary>
        /// 创建RCS参数拼接
        /// </summary>
        /// <returns></returns>
        private async Task<SerialOpticalComModel> StructureApiParaAsync(string apiType,object para,bool isResult)
        {
            SerialOpticalComModel result = new SerialOpticalComModel();
            var data = await _rcsDomainService.StructureRcsParaAsync(ConstStringData.SerialNet_HikRCS, apiType, para, isResult);
            if (data is null)
            {
                return null;
            }
            result.funCode = await opticalFunCodeApiMap.GetFunCodeBaseApi(data.rcsApi);
            result.type = (OpticalMsgType)data.info.type;
            result.reqCode = data.info.reqCode;
            result.msg = data.info.data;
            await _rcsOvertimeDomainService.AddWaitQuere(data.info.reqCode, apiType,para);
            return result;
        }
        /// <summary>
        /// 拼接AGV外设参数
        /// </summary>
        /// peripheral 外设类型
        /// <returns></returns>
        private async Task<SerialOpticalComModel> StructureAgvPeripheralParaAsync(string peripheral,object para)
        {
            SerialOpticalComModel result = new SerialOpticalComModel();
            var data = await _rcsDomainService.StructAgvPeripheralParaAsync(peripheral, para);
            if (data is null)
            {
                return null;
            }
            result.funCode = await opticalFunCodeApiMap.GetFunCodeBaseAgvPeripheral(peripheral);
            result.type = (OpticalMsgType)data.type;
            result.reqCode = data.reqCode;
            result.msg = data.data;
            return result;
        }
        
        /// <summary>
        /// AGV继续执行暂停的任务
        /// </summary>
        /// <param name="optical"></param>
        /// <returns></returns>
        private async Task AgvContinueAsync(string opticalId, string taskCode)
        {
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (opticalInfo is null)
            {
                Log.Error($"AGV继续执行任务发送时，光通信信息获取失败");
                return;
            }
            await SendContinueTaskAsync(opticalInfo, taskCode);
        }

        /// <summary>
        /// 任务状态查询接口返回
        /// </summary>
        /// <returns></returns>
        private async Task TaskInfoUpdateAsync(List<TaskStatusModel> infos, string reqCode, string eqCode)
        {
            await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
        }
        /// <summary>
        /// 同步地图接口调用返回处理
        /// </summary>
        /// <returns></returns>
        private async Task MapInfoUpdateAsync(List<MapInfoModel> infos, string reqCode, string eqCode)
        {
            await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
        }
        /// <summary>
        /// PodBerthAndMat 接口查询返回处理
        /// </summary>
        /// <returns></returns>
        private async Task PodBerthAndMatAsync(List<PodBerthAndMatInfoModel> infos, string reqCode, string eqCode)
        {
            await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
        }
        private async Task<bool> BatchUpdateTaskState(TaskDto task, TaskState state,string errMsg)
        {
            TaskAnalysisModel model = new TaskAnalysisModel();

            model.taskId = task.id;
            model.orderId = task.orderCode;
            model.taskState = state;
            model.errMsg = errMsg;
            return await UpdateTaskStateAsync(model);
        }
        /// <summary>
        /// 更新指定任务状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private async Task<bool> UpdateTaskStateAsync(TaskAnalysisModel info)
        {
            if (info.taskState == TaskState.Err)
            {
                await _upperSysDomainService.OrderAbnormalReportAsync(info.orderId,info.errMsg);
            }
            UpdateTaskStateDto dto = new UpdateTaskStateDto();
            dto.id = info.taskId;
            dto.state = info.taskState.ToString();
            dto.errMsg = info.errMsg;
            dto.agvCode = info.agvId;
            dto.batchNumber = info.batchNumber;
            dto.batchTaskSeq = info.batchSeq;
            return await _taskService.UpdateTaskStateAsync(dto);
        }
        /// <summary>
        /// 任务下发前准备
        /// </summary>
        /// <returns></returns>
        private async Task<bool> TaskSendPreProcessAsync(OpticalTaskModel opticalTaskModel)
        {
            if (opticalTaskModel.sendTaskOptical is null)
            { 
                return false;
            }
            //占用AGV所在巷道
            if (!await _commonResDomainService.RoadwayStateUpdateAsync(opticalTaskModel.sendTaskOptical.customInfo.roadwayCode,true))
            {
                return false;
            }
            //占用任务点所在巷道
            if (opticalTaskModel.endTaskOptical is not null)
            {
                if (!await _commonResDomainService.RoadwayStateUpdateAsync(opticalTaskModel.endTaskOptical.customInfo.roadwayCode, true))
                {
                    await _commonResDomainService.RoadwayStateUpdateAsync(opticalTaskModel.sendTaskOptical.customInfo.roadwayCode, false);
                    return false;
                }
            }
            return true;
        }
        
        /// <summary>
        /// 获取任务模板号
        /// </summary>
        /// <returns></returns>
        private string GetTaskTemplateCode(string taskType,bool isTransferRoadway)
        {
            if (taskType == AppSettingsConstVars.TransportOutboundTaskName)
            {
                return AppSettingsConstVars.TransportTaskOutbound;
            }
            else if (taskType == AppSettingsConstVars.TransportEmptyboxTaskName)
            {
                return AppSettingsConstVars.TransportTaskEmptybox;
            }
            else if (taskType == AppSettingsConstVars.TransportTaskName)
            {
                return AppSettingsConstVars.TransportTask;
            }
            else if (taskType == AppSettingsConstVars.WarehousingTaskName)
            {
                return isTransferRoadway ? AppSettingsConstVars.WarehousingTransferRoadway : AppSettingsConstVars.WarehousingTaskSingleRoadway;
            }
            else if (taskType == AppSettingsConstVars.OutboundTaskName)
            {
                return isTransferRoadway ? AppSettingsConstVars.OutboundTaskTransferRoadway : AppSettingsConstVars.OutboundTaskSingleRoadway;
            }
            return null;
        }
        /// <summary>
        /// CTU任务开始申请处理
        /// </summary>
        /// <returns></returns>
        private async Task CTUStartTaskApplyManageAsync(string opticalId, string agvId, string taskCode)
        {
            var (state,batchNumber,rcsTaskInfos) = await QueryWaitTaskStateBaseRcstask(taskCode);
            if (state == BatchTaskState.allowStart)
            {
                await UpdateWaitStartBatchTaskAsync(batchNumber, BatchTaskState.executing);
                //获取对应光通信模块的信息
                var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
                foreach (var rcsTaskInfo in rcsTaskInfos)
                {
                    //AGV继续执行任务
                    await SendContinueTaskAsync(opticalInfo, rcsTaskInfo.Value);
                }
            }
        }
        /// <summary>
        /// CTU取货任务申请处理
        /// </summary>
        /// <returns></returns>
        private async Task CTUPickGoosApplyManageAsync(string opticalId, string agvId, string taskCode)
        {
            var (state, batchNumber, rcsTaskInfos) = await QueryWaitTaskStateBaseRcstask(taskCode);
            //查询该任务的物料信息
            var taskInfo = await _taskService.QueryTaskBaseRcsTaskCodeAsync(taskCode);

            //判断传送台当前可取物料信息

            //发送取动作
        }
        /// <summary>
        /// 查询指定任务批号下的所有任务
        /// </summary>
        /// <param name=""></param>
        private void QueryBatchTaskInfos(string taskCode)
        { 
            
        }

        /// <summary>
        /// 根据同组任务数量获取对应的任务模板
        /// </summary>
        /// <returns></returns>
        private string GetTaskTemplateBaseNumber(int num)
        {
            if (num == 1)
            {
                return "1";
            }
            else if (num == 2)
            {
                return "2";
            }
            else if (num == 3)
            {
                return "3";
            }
            else if (num == 4)
            {
                return "4";
            }
            return string.Empty;
        }
        /// <summary>
        /// 判断当前是否可以充电
        /// </summary>
        /// <returns></returns>
        private async Task<bool> ChargeChecker(RunEqInfoModel<OpticalCustomInfoModel> curOptical)
        {
            var opticalInfo = await _opticalDomainService.QueryChargeOpticalAsync();
            if (opticalInfo is not null)
            {
                if (await _commonResDomainService.QueryCommonRoadwayStateAsync())
                {
                    //锁定充电点位
                    return await _opticalDomainService.LockChargeOpticalChangeAsync(opticalInfo.id, true);
                }
            }
            return false;
        }
        #endregion

        #region RCS服务事件处理
        /// <summary>
        /// rcs普通返回值处理
        /// </summary>
        /// <returns></returns>
        private async Task ResultAsync(ResultModel info, string reqCode, string eqCode)
        {
            var removeInfo = await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
            if (info.code != "0")
            {
                Log.Error($"RCS接口{removeInfo.apiName}调用返回异常Code:{info.code}Msg:{info.message}");
            }
        }
        /// <summary>
        /// rcs带Data返回值
        /// </summary>
        /// <returns></returns>
        private async Task ResultDataAsync(ResultDataModel info, string reqCode, string eqCode)
        {
            var removeInfo = await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
            if (info.code != "0")
            {
                Log.Error($"RCS接口{removeInfo.apiName}调用返回异常Code:{info.code}Msg:{info.message}Data:{info.data}");
                return;
            }
            if (removeInfo.apiName == ConstStringData.CreatTask_WCSApi)
            {
                var taskData = removeInfo.para as TaskDto;
                //更新RCS生成的任务ID
                if (taskData != null)
                {
                    var taskInfo = await _taskService.UpdateRcsTaskCodeBaseId(taskData.id, info.code);
                    if (taskInfo is not null)
                    {
                        //更新至等待任务开始队列
                        if (taskData.taskType == AppSettingsConstVars.WarehousingTaskName
                            || taskData.taskType == AppSettingsConstVars.OutboundTaskName)
                        {
                            await AddWaitStartBatchTaskSubAsync(taskInfo.batchNumber, taskInfo.id.ToString(), taskInfo.rcsTaskCode, taskInfo.batchTaskSeq);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 离开公共巷道处理
        /// </summary>
        /// <returns></returns>
        private async Task LeaveCommonRoadwayManageAsync(string opticalId, string agvId, string taskCode)
        {
            //释放公共巷道占用状态
            await _commonResDomainService.ReleaseCommonRoadwayAsync();
            var (state, batchNumber, rcsTaskInfos) = await QueryWaitTaskStateBaseRcstask(taskCode);
            if (state != BatchTaskState.enterRoadway)
            {
                return;
            }
            await UpdateWaitStartBatchTaskAsync(batchNumber, BatchTaskState.waitPickgoods);
            //获取对应光通信模块的信息
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            foreach (var rcsTaskInfo in rcsTaskInfos)
            {
                //AGV继续执行任务
                await SendContinueTaskAsync(opticalInfo, rcsTaskInfo.Value);
            }
        }
        /// <summary>
        /// 进入公共巷道处理
        /// </summary>
        /// <returns></returns>
        private async Task EnterCommonRoadwayManageAsync(string opticalId, string agvId, string taskCode)
        {
            //公共巷道占用中等待
            if (!await _commonResDomainService.QueryCommonRoadwayStateAsync())
            {
                await _commonResDomainService.AddWaitCommonRoadwayQueueAsync(opticalId, agvId);
                return;
            }
            //获取对应光通信模块的信息
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            //光通信设备信息获取失败--AGV在该点等待
            if (opticalInfo is null)
            {
                await _commonResDomainService.AddWaitCommonRoadwayQueueAsync(opticalId, agvId);
                Log.Error($"光通信模块{opticalId}信息获取失败!");
                return;
            }

            //释放当前所在巷道
            await _commonResDomainService.ReleaseRoadwayAsync(opticalInfo.customInfo.roadwayCode);

            //获取改任务批次所有任务
            var (state, batchNumber, rcsTaskInfos) = await QueryWaitTaskStateBaseRcstask(taskCode);
            if (state != BatchTaskState.executing)
            {
                return;
            }
            await UpdateWaitStartBatchTaskAsync(batchNumber, BatchTaskState.enterRoadway);
            foreach (var rcsTaskInfo in rcsTaskInfos)
            {
                //AGV继续执行任务
                await SendContinueTaskAsync(opticalInfo, rcsTaskInfo.Value);
            }
        }
        /// <summary>
        /// 充电申请
        /// </summary>
        /// <returns></returns>
        private async Task ChargeReportAsync(string opticalId, string reqCode)
        {
            //获取对应光通信模块的信息
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (opticalInfo is null)
            {
                return;
            }
            await SendChargeReportResultAsync(opticalInfo, reqCode, await ChargeChecker(opticalInfo));
        }
        /// <summary>
        /// 任务执行完成操作
        /// </summary>
        /// <param name="agvId"></param>
        /// <returns></returns>
        private async Task TaskEndAsync(string opticalId, string taskCode)
        {
            //获取对应光通信模块的信息
            var opticalInfo = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (opticalInfo is null)
            {
                return;
            }
            //三楼CTU任务
            if (opticalInfo.areaCode == AppSettingsConstVars.Area_2)
            {
                //释放当前所在巷道
                await _commonResDomainService.ReleaseRoadwayAsync(opticalInfo.customInfo.roadwayCode);
                //更新订单完成信息至WMS
                var taskInfo = await _taskService.UpdateTaskStateBaseRcsTaskIdAsync(taskCode);
                if (taskInfo is not null)
                {
                    await _upperSysDomainService.OrderCompleteReportAsync(taskInfo.orderCode);

                    //删除任务开始等待队列中的批次任务
                    await RemoveWaitStartBatchTask(taskInfo.batchNumber);
                    //await Task.WhenAll(addOrder);
                }
            }
            //二楼滚筒任务
            else if (opticalInfo.areaCode == AppSettingsConstVars.Area_1)
            {
                //更新订单完成信息至WMS
                var taskInfo = await _taskService.UpdateTaskStateBaseRcsTaskIdAsync(taskCode);
                if (taskInfo is not null)
                {
                    await _upperSysDomainService.OrderCompleteReportAsync(taskInfo.orderCode);
                }
            }
        }
        /// <summary>
        /// 任务执行暂停操作
        /// </summary>
        /// <param name="opticalId"></param>
        /// <param name="taskCode"></param>
        /// <returns></returns>
        private async Task TaskPauseAsync(string opticalId, string rcstaskCode, string info, string agvCode)
        {
            var taskInfo = await _taskService.QueryTaskBaseRcsTaskCodeAsync(rcstaskCode);
            if (taskInfo is null)
            {
                Log.Error($"agvCallback接口上传的任务编号错误");
                return;
            }
            //CTU入库任务
            if (taskInfo.taskType == AppSettingsConstVars.WarehousingTaskName)
            {
                await Pause_CTUWarehousingTaskAsync(opticalId, taskInfo, info, agvCode, rcstaskCode);
            }
            //CTU出库任务
            else if (taskInfo.taskType == AppSettingsConstVars.OutboundTaskName)
            {
                await Pause_CTUOutboundTaskAsync(opticalId, taskInfo, info, agvCode, rcstaskCode);
            }
            //滚筒出库任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportOutboundTaskName)
            {
                await Pause_TransportOutboundTaskAsync(opticalId, taskInfo, info, agvCode, rcstaskCode);
            }
            //滚筒空箱回库任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportEmptyboxTaskName)
            {
                await Pause_TransportEmptyboxTaskAsync(opticalId, taskInfo, info, agvCode, rcstaskCode);
            }
            //滚筒物料转运任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportTaskName)
            {
                await Pause_TransportTaskAsync(opticalId, taskInfo, info, agvCode, rcstaskCode);
            }
        }
        /// <summary>
        /// AGV信息更新--agv状态查询接口返回
        /// </summary>
        /// <returns></returns>
        private async Task AgvInfoUpdateAsync(List<AgvInfoModel> infos, string reqCode, string eqCode)
        {
            await _rcsOvertimeDomainService.RemoveWaitQuere(reqCode);
            if (infos is not null && infos.Any())
            {
                if (int.TryParse(eqCode, out int id))
                {
                    Log.Error($"光通信{eqCode}ID错误!");
                    return;
                }
                var mapSite = await _opticalDomainService.QueryEqSiteAsync(id);
                if (mapSite is null)
                {
                    Log.Error($"光通信{eqCode}设备查询失败!");
                    return;
                }
                await _agvDomainService.UpdateAgvInfoAsync(infos, eqCode);
            }
        }
        /// <summary>
        /// AGV超时上报超时异常
        /// </summary>
        /// <returns></returns>
        private async Task AgvOverTimeAsync(string agvCode, string lastStn)
        {
            AbnormalInfoModel abnormalInfoModel = new AbnormalInfoModel();
            Log.Information($"Agv{agvCode}失去连接，上一个点位是{lastStn}");
            await _upperSysDomainService.AbnormalReportAsync(JsonConvert.SerializeObject(abnormalInfoModel));
        }
        /// <summary>
        /// AGV异常处理
        /// </summary>
        /// <returns></returns>
        private async Task AgvAbnormalAsync(ManageAgvModel agvinfo)
        {
            Log.Information($"Agv{agvinfo.agvCode}异常:{agvinfo.abnormalMsg}");
            var agvInfo = agvinfo;
        }

        /// <summary>
        /// AGV异常告警处理
        /// </summary>
        /// <returns></returns>
        private async Task WarnProcessAsync(string opticalId, WarnModel model)
        {
            if (model.data is null)
            {
                return;
            }
            model.data.ForEach(d => 
            {
                Log.Information($"Agv{d.robotCode}告警:{d.warnContent}时间:{d.beginDate}任务:{d.taskCode}");
            });
        }
        #endregion

        #region 超时处理
        private async Task CreatTaskOvertimeAsync(string agvCode)
        {
            //更新任务状态
            await _taskService.UpdateTaskStateBaseAgvIdAsync(agvCode);
            //异常流程处理

        }
        #endregion

        #region 发送光通信数据
        /// <summary>
        /// 滚筒控制发送
        /// </summary>
        /// <returns></returns>
        private async Task RollerControlAsync(RunEqInfoModel<OpticalCustomInfoModel> optical,string modbusFunCode, RollerWriteModel info)
        {
            RollerOpticalModel rollerOpticalModel = new RollerOpticalModel();
            rollerOpticalModel.modbusFunCode = modbusFunCode;
            rollerOpticalModel.data = info;
            await StructureAgvPeripheralParaAsync(ConstStringData.Roller_Peripheral, rollerOpticalModel);
        }
        /// <summary>
        /// 指示灯控制发送
        /// </summary>
        /// <returns></returns>
        private async Task PromptlightControlAsync(RunEqInfoModel<OpticalCustomInfoModel> optical, string modbusFunCode, PromptlightState promptlightState)
        {
            PromptlightOpticalModel promptlightOpticalModel = new PromptlightOpticalModel();
            promptlightOpticalModel.modebusFunCode = modbusFunCode;
            promptlightOpticalModel.promptlightState = promptlightState;
            await StructureAgvPeripheralParaAsync(ConstStringData.Promptlight_Peripheral, promptlightOpticalModel);
        }

        /// <summary>
        /// 下发任务
        /// </summary>
        /// <returns></returns>
        private async Task DistributeInfoAsync(RunEqInfoModel<OpticalCustomInfoModel> optical, string api, object para,bool isResult)
        {
            if (optical is not null)
            {
                var sendModel = await StructureApiParaAsync(api, para, isResult);
                await _opticalDomainService.SendMsgAsync(sendModel, optical.id);
            }
        }
       
        /// <summary>
        /// 发送查询AGV状态
        /// </summary>
        /// <param name="opticalId"></param>
        /// <returns></returns>
        private async Task<SerialOpticalComModel> OpticalOppsiteProcess(int opticalId)
        {
            var data = await _rcsDomainService.StructureRcsParaAsync(ConstStringData.SerialNet_HikRCS, ConstStringData.QueryAgvStatus_WCSApi, "123",false);
            if (data is null) return null;
            SerialOpticalComModel model = new SerialOpticalComModel();
            model.funCode = await opticalFunCodeApiMap.GetFunCodeBaseApi(data.rcsApi);
            model.type = (OpticalMsgType)data.info.type;
            model.reqCode = data.info.reqCode;
            model.msg = data.info.data;
            await _rcsOvertimeDomainService.AddWaitQuere(data.info.reqCode, ConstStringData.QueryAgvStatus_WCSApi, data);
            return model;
        }
        /// <summary>
        /// 向指定AGV发送继续执行任务
        /// </summary>
        /// <returns></returns>
        private async Task SendContinueTaskAsync(RunEqInfoModel<OpticalCustomInfoModel> opticalInfo,string taskCode = "")
        {
            var data = await CreatContinueTaskParaAsync(taskCode);
            await DistributeInfoAsync(opticalInfo, ConstStringData.ContinueTask_WCSApi, data,false);
        }
        /// <summary>
        /// 恢复AGV运行
        /// </summary>
        /// <returns></returns>
        private async Task SendResumeRobotAsync()
        {

        }
        /// <summary>
        /// 下发预调度指令
        /// </summary>
        /// <returns></returns>
        private async Task SendPreScheduleTaskAsync(RunEqInfoModel<OpticalCustomInfoModel> opticalInfo, string positionCode, string catchCount,bool isFirstTask = true)
        {
            var data = await CreatPreScheduleTaskParaAsync(positionCode, catchCount, isFirstTask);
            await DistributeInfoAsync(opticalInfo, ConstStringData.GenPreScheduleTask_WCSApi, data, false);
        }
        /// <summary>
        /// 创建继续执行任务参数
        /// </summary>
        /// <returns></returns>
        private async Task<ContinueTaskModel> CreatContinueTaskParaAsync(string taskCode)
        {
            return await Task.Run(() =>
            {
                ContinueTaskModel continueTaskModel = new();
                continueTaskModel.taskCode = taskCode;
                return continueTaskModel;
            });
        }
        /// <summary>
        /// 创建预调度参数
        /// </summary>
        /// <param name="positionCode">预调度的位置或仓位 </param>
        /// <param name="isFirstTask">是否为本次预调度下发的第一条任务</param>
        /// <returns></returns>
        private async Task<GenPreScheduleTaskModel> CreatPreScheduleTaskParaAsync(string positionCode, string cacheCount,bool isFirstTask=true)
        {
            GenPreScheduleTaskModel genPreScheduleTask = new();
            genPreScheduleTask.positionCode = positionCode;
            genPreScheduleTask.nextTask = AppSettingsConstVars.PreTaskTime;
            genPreScheduleTask.agvTyp = ConstStringData.CTU_agvType;
            genPreScheduleTask.useableLayers = "1";
            genPreScheduleTask.cacheCount = cacheCount;
            genPreScheduleTask.update = "0";
            return genPreScheduleTask;
        }
        /// <summary>
        /// 发送充电请求回复
        /// </summary>
        /// <returns></returns>
        private async Task SendChargeReportResultAsync(RunEqInfoModel<OpticalCustomInfoModel> opticalInfo,string reqCode,bool flag)
        {
            ChargeRequestResultModel chargeRequestResultModel = new ChargeRequestResultModel();
            chargeRequestResultModel.code = flag ? ConstStringData.Success_Code : ConstStringData.Fail_Code;
            chargeRequestResultModel.message = flag ? ConstStringData.Success_Result : ConstStringData.Fail_Result;
            chargeRequestResultModel.reqCode = reqCode;
            await DistributeInfoAsync(opticalInfo,ConstStringData.ChargeReport_WCSApi, chargeRequestResultModel, true);
        }
        #endregion

        #region 任务暂停处理
        /// <summary>
        /// CTU入库任务暂停处理
        /// </summary>
        /// <returns></returns>
        private async Task Pause_CTUWarehousingTaskAsync(string opticalId,TaskDto taskDto,string curInfo, string agvCode,string taskCode)
        {
            if (curInfo == AppSettingsConstVars.EnterRoadwayMethod)
            {
                await EnterCommonRoadwayManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.ExitRoadwayMethod)
            {
                await LeaveCommonRoadwayManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.StartTaskMethod)
            {
                await CTUStartTaskApplyManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.PickGoodsMethod)
            {
                await CTUPickGoosApplyManageAsync(opticalId, agvCode, taskCode);
            }
        }
        /// <summary>
        /// CTU出库任务暂停处理
        /// </summary>
        /// <returns></returns>
        private async Task Pause_CTUOutboundTaskAsync(string opticalId, TaskDto taskDto, string curInfo, string agvCode, string taskCode)
        {
            var curOptical = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (curOptical is null)
            {
                Log.Error($"当前所在位置光通信信息获取失败");
                return;
            }
            if (curInfo == AppSettingsConstVars.EnterRoadwayMethod)
            {
                await EnterCommonRoadwayManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.ExitRoadwayMethod)
            {
                await LeaveCommonRoadwayManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.StartTaskMethod)
            {
                await CTUStartTaskApplyManageAsync(opticalId, agvCode, taskCode);
            }
            else if (curInfo == AppSettingsConstVars.PickGoodsMethod)
            {
                await CTUPickGoosApplyManageAsync(opticalId, agvCode, taskCode);
            }
        }
        /// <summary>
        /// 滚筒出库搬运任务暂停处理
        /// </summary>
        /// <returns></returns>
        private async Task Pause_TransportOutboundTaskAsync(string opticalId, TaskDto taskDto, string curInfo, string agvCode,string taskCode)
        {
            var curOptical = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (curOptical is null)
            {
                Log.Error($"当前所在位置光通信信息获取失败");
                return;
            }
            //到达放货点
            if (curInfo == AppSettingsConstVars.ArriveTransferPutPointMethod)
            {
                //点亮提示灯
                await PromptlightControlAsync(curOptical, ConstStringData.Writ_03, PromptlightState.open);
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.DownRollerMatNull;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
            //出库
            else if (curInfo == AppSettingsConstVars.RollerOutboundMethod)
            {
                var data = CreatRollerInfo(RollerWriteState.Idle, RollerWriteState.LeftLoad);
                //下层滚筒转动
                await RollerControlAsync(curOptical, ConstStringData.Writ_03, data);
                //传送带转动
                await ConveyorBeltControlAsync(false, AppSettingsConstVars.Line_2, "","");
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.DownRollerMatHave;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
            //入库
            else if (curInfo == AppSettingsConstVars.RollerWarehousingMethod)
            {
                var data = CreatRollerInfo(RollerWriteState.LeftLoad,RollerWriteState.Idle);
                //上层滚筒转动
                await RollerControlAsync(curOptical, ConstStringData.Writ_03, data);
                //传送带转动
                await ConveyorBeltControlAsync(true, AppSettingsConstVars.Line_2, "", "");
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.UpRollerMatNull;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
        }
        /// <summary>
        /// 滚筒空箱回库任务暂停处理
        /// </summary>
        /// <returns></returns>
        private async Task Pause_TransportEmptyboxTaskAsync(string opticalId, TaskDto taskDto, string curInfo, string agvCode, string taskCode)
        {
            var curOptical = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (curOptical is null)
            {
                Log.Error($"当前所在位置光通信信息获取失败");
                return;
            }
            //到达中间点
            if (curInfo == AppSettingsConstVars.ArriveTransferPickPointMethod)
            {
                //点亮提示灯
                await PromptlightControlAsync(curOptical, ConstStringData.Writ_03, PromptlightState.open);
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.UpRollerMatHave;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
            //入库
            else if (curInfo == AppSettingsConstVars.RollerWarehousingMethod)
            {
                var data = CreatRollerInfo(RollerWriteState.LeftLoad, RollerWriteState.Idle);
                //上层滚筒转动
                await RollerControlAsync(curOptical, ConstStringData.Writ_03, data);
                //传送带转动
                await ConveyorBeltControlAsync(true, AppSettingsConstVars.Line_2, "", "");
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.UpRollerMatNull;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
        }
        /// <summary>
        /// 滚筒物料转运任务暂停处理
        /// </summary>
        /// <returns></returns>
        private async Task Pause_TransportTaskAsync(string opticalId, TaskDto taskDto, string curInfo, string agvCode, string taskCode)
        {
            var curOptical = await _opticalDomainService.QueryOpticalInfoAsync(opticalId);
            if (curOptical is null)
            {
                Log.Error($"当前所在位置光通信信息获取失败");
                return;
            }
            //到达中间点
            if (curInfo == AppSettingsConstVars.ArriveTransferPickPointMethod)
            {
                //点亮提示灯
                await PromptlightControlAsync(curOptical, ConstStringData.Writ_03, PromptlightState.open);
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.DownRollerMatHave;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
            //到达搬运的放置点
            else if (curInfo == AppSettingsConstVars.ArriveTransferPutPointMethod)
            {
                //点亮提示灯
                await PromptlightControlAsync(curOptical, ConstStringData.Writ_03, PromptlightState.open);
                //添加AGV等待结束判断条件
                AgvWaitInfoModel model = new AgvWaitInfoModel();
                model.agvCode = agvCode;
                model.opticalId = curOptical.id.ToString();
                model.type = AgvWaitState.DownRollerMatNull;
                model.taskCode = taskCode;
                await _agvDomainService.AddWaitAgvAsync(agvCode, model);
            }
        }
        /// <summary>
        /// 根据当前点位在任务中位置判断当前要进行的动作类型
        /// </summary>
        /// <param name="taskInfo"></param>
        /// <param name="curInfo"></param>
        /// <returns></returns>
        private async Task<string> GetCurStnName(TaskDto taskInfo, string curInfo)
        {
            string result = "";
            //CTU入库任务
            if (taskInfo.taskType == AppSettingsConstVars.WarehousingTaskName)
            {
                
            }
            //CTU出库任务
            else if (taskInfo.taskType == AppSettingsConstVars.OutboundTaskName)
            {
                
            }
            //滚筒出库任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportOutboundTaskName)
            {
               
            }
            //滚筒空箱回库任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportEmptyboxTaskName)
            {
                
            }
            //滚筒物料转运任务
            else if (taskInfo.taskType == AppSettingsConstVars.TransportTaskName)
            {
                
            }
            return result;
        }
        #endregion

        #region 创建任务参数生成
        /// <summary>
        /// 创建任务参数生成
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatTaskParaProcessAsync(TaskDto task, OpticalTaskModel opticalInfo,string templateCode)
        {
            CreatTaskModel creatTaskModel = null;
            //CTU入库任务
            if (task.taskType == AppSettingsConstVars.WarehousingTaskName)
            {
                creatTaskModel = opticalInfo.transferRoadway ?
                    await CreatTransferRoadwayInTask(opticalInfo,task.targetStorage, templateCode, task.areaCode)
                    : await CreatSingleRoadwayInTask(opticalInfo.sendTaskOptical.mapCode, task.targetStorage, templateCode, task.areaCode);
            }
            //CTU出库任务
            else if (task.taskType == AppSettingsConstVars.OutboundTaskName)
            {
                creatTaskModel = opticalInfo.transferRoadway ?
                        await CreatTransferRoadwayOutTask(opticalInfo, task.targetStorage, templateCode, task.areaCode)
                        : await CreatSingleRoadwayOutTask(opticalInfo.sendTaskOptical.mapCode, task.targetStorage, templateCode, task.areaCode);
            }
            //滚筒出库
            else if (task.taskType == AppSettingsConstVars.TransportOutboundTaskName)
            {
                creatTaskModel = await CreatRollerOutboundTask(task.targetStorage, templateCode, task.areaCode);
            }
            //滚筒空箱入库
            else if (task.taskType == AppSettingsConstVars.TransportEmptyboxTaskName)
            {
                creatTaskModel = await CreatRollerEmptyboxTask(task.targetStorage, templateCode, task.areaCode);
            }
            //滚筒中转物料
            else if (task.taskType == AppSettingsConstVars.TransportTaskName)
            {
                creatTaskModel = await CreatRollerTransportTask(task.sourceStorage,task.targetStorage,templateCode,task.areaCode);
            }
            return creatTaskModel;
        }
        /// <summary>
        /// 滚筒物料转运任务
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatRollerTransportTask(string srcStorage,string targetStorage, string templateCode, string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();
            creatTaskModel.taskTyp = templateCode;

            //任务点
            positionInfo srcPoint = new positionInfo();
            var srcInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (srcInfo is null || srcInfo.mapPositionCode is null)
            {
                return null;
            }
            srcPoint.positionCode = srcInfo.mapPositionCode;
            srcPoint.type = HikRcsConst.LocationCode;

            //目标点
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;

            //回到休息点
            positionInfo restPoint = new positionInfo();
            var restOptical = await _opticalDomainService.QueryUnavailableOpticalBaseTypeAsync(OpticalType.Rest, AppSettingsConstVars.Area_2);
            if (restOptical is null)
            {
                return null;
            }
            restPoint.positionCode = restOptical.mapCode;
            restPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(srcPoint);
            positionInfos.Add(targetPoint);
            positionInfos.Add(restPoint);
            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }

        /// <summary>
        /// 滚筒空箱回库
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatRollerEmptyboxTask(string targetStorage, string templateCode, string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();
            creatTaskModel.taskTyp = templateCode;

            //目标点
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;
            //库房点
            positionInfo warehousePoint = new positionInfo();
            var warehouseOptical = await _opticalDomainService.QueryUnavailableOpticalBaseTypeAsync(OpticalType.Warehouse,AppSettingsConstVars.Area_2);
            if (warehouseOptical is null)
            {
                return null;
            }
            warehousePoint.positionCode = warehouseOptical.mapCode;
            warehousePoint.type = HikRcsConst.LocationCode;
            //回到休息点
            positionInfo restPoint = new positionInfo();
            var restOptical = await _opticalDomainService.QueryUnavailableOpticalBaseTypeAsync(OpticalType.Rest, AppSettingsConstVars.Area_2);
            if (restOptical is null)
            {
                return null;
            }
            restPoint.positionCode = restOptical.mapCode;
            restPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(targetPoint);
            positionInfos.Add(warehousePoint);
            positionInfos.Add(restPoint);
            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }
        /// <summary>
        /// 滚筒出库
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatRollerOutboundTask(string targetStorage, string templateCode, string areaCode) 
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();
            creatTaskModel.taskTyp = templateCode;
            //库房点
            positionInfo warehousePoint = new positionInfo();
            var warehouseOptical = await _opticalDomainService.QueryUnavailableOpticalBaseTypeAsync(OpticalType.Warehouse, AppSettingsConstVars.Area_2);
            if (warehouseOptical is null)
            {
                return null;
            }
            warehousePoint.positionCode = warehouseOptical.mapCode;
            warehousePoint.type = HikRcsConst.LocationCode;
            //目标点
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;
            //库房点
            positionInfo secPoint = new positionInfo();
            secPoint.positionCode = warehouseOptical.mapCode;
            secPoint.type = HikRcsConst.LocationCode;
            //回到休息点
            positionInfo restPoint = new positionInfo();
            var restOptical = await _opticalDomainService.QueryUnavailableOpticalBaseTypeAsync(OpticalType.Rest, AppSettingsConstVars.Area_2);
            if (restOptical is null)
            {
                return null;
            }
            restPoint.positionCode = restOptical.mapCode;
            restPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(warehousePoint);
            positionInfos.Add(targetPoint);
            positionInfos.Add(secPoint);
            positionInfos.Add(restPoint);
            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }

        /// <summary>
        /// 单通道任务入库
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatSingleRoadwayInTask(string standbyCode, string targetStorage, string templateCode,
                                                                    string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();

            creatTaskModel.taskTyp = templateCode;
            ////任务起始点
            positionInfo firstPoint = new positionInfo();
            firstPoint.positionCode = standbyCode;
            firstPoint.type = HikRcsConst.LocationCode;
            //任务目标点
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;
            //回到待命点
            positionInfo endPoint = new positionInfo();
            endPoint.positionCode = standbyCode;
            endPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(firstPoint);
            positionInfos.Add(targetPoint);
            positionInfos.Add(endPoint);

            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }
        /// <summary>
        /// 单通道出库任务
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatSingleRoadwayOutTask(string standbyCode, string targetStorage, string templateCode,
                                                                    string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();

            creatTaskModel.taskTyp = templateCode;
            //任务目标点
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;

            //回到待命点
            positionInfo endPoint = new positionInfo();
            endPoint.positionCode = standbyCode;
            endPoint.type = HikRcsConst.LocationCode;

            positionInfos.Add(targetPoint);
            positionInfos.Add(endPoint);
            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }
        /// <summary>
        /// 创建需要从其他通道调车的任务-入库任务
        /// </summary>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatTransferRoadwayInTask(OpticalTaskModel opticalInfos, string targetStorage, string templateCode, string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();

            creatTaskModel.taskTyp = templateCode;
            //第一个控制点
            positionInfo firstPoint = new positionInfo();
            firstPoint.positionCode = opticalInfos.ctrTaskOptical?.mapCode;
            firstPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(firstPoint);
            //第二个控制点
            positionInfo ctrPoint = new positionInfo();
            ctrPoint.positionCode = opticalInfos.ctr1TaskOptical?.mapCode;
            ctrPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(ctrPoint);
            //取物料任务点
            positionInfo standyPoint = new positionInfo();
            standyPoint.positionCode = opticalInfos.endTaskOptical?.mapCode;
            standyPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(standyPoint);
            //目标仓位
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            firstPoint.positionCode = tarInfo.mapPositionCode;
            targetPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(targetPoint);
            //任务所在巷道的待命点停车
            positionInfo endtPoint = new positionInfo();
            endtPoint.positionCode = opticalInfos.endTaskOptical?.mapCode;
            endtPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(endtPoint);
            creatTaskModel.positionCodePath = positionInfos;

            return creatTaskModel;
        }
        /// <summary>
        /// 创建需要从其他通道调车的任务-出库任务
        /// </summary>
        /// <param name="ctrCode"></param>
        /// <param name="standbyCode"></param>
        /// <param name="targetStorage"></param>
        /// <param name="templateCode"></param>
        /// <returns></returns>
        private async Task<CreatTaskModel> CreatTransferRoadwayOutTask(OpticalTaskModel opticalInfos, string targetStorage, string templateCode, string areaCode)
        {
            CreatTaskModel creatTaskModel = new();
            List<positionInfo> positionInfos = new();

            creatTaskModel.taskTyp = templateCode;
            //第一个控制点
            positionInfo firstPoint = new positionInfo();
            firstPoint.positionCode = opticalInfos.ctrTaskOptical?.mapCode;
            firstPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(firstPoint);
            //第二个控制点
            positionInfo ctrPoint = new positionInfo();
            ctrPoint.positionCode = opticalInfos.ctr1TaskOptical?.mapCode;
            ctrPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(ctrPoint);
            //目标仓位
            positionInfo targetPoint = new positionInfo();
            var tarInfo = await _mapPositionService.QueryMapPositionBaseBinNumberAsync(areaCode, targetStorage);
            if (tarInfo is null || tarInfo.mapPositionCode is null)
            {
                return null;
            }
            targetPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(targetPoint);
            //出库任务点
            positionInfo endtPoint = new positionInfo();
            endtPoint.positionCode = opticalInfos.endTaskOptical?.mapCode;
            endtPoint.type = HikRcsConst.LocationCode;
            positionInfos.Add(endtPoint);
            creatTaskModel.positionCodePath = positionInfos;
            return creatTaskModel;
        }

        #endregion

        #region 传送带处理
        /// <summary>
        /// 传送带控制
        /// </summary>
        /// <returns></returns>
        private async Task ConveyorBeltControlAsync(bool isWarehouse,string lineName,string matType,string site)
        {
            if (isWarehouse)
            {
                await _lineDomainService.WriteWarehousingMatTypeAsync(lineName, matType);
            }
            else
            {
                await _lineDomainService.OutboundProcessAsync(lineName, site);
            }
        }
        #endregion

        #region CTU等待开始批次任务管理
        private bool SubTaskCheck(Dictionary<string,string> infos)
        {
            foreach (var item in infos)
            {
                if (string.IsNullOrEmpty(item.Value))
                { 
                    return false;
                }
            }
            return true;
        }
        private async Task AddWaitStartBatchTaskSubAsync(string batchNumber,string taskId, string rcsTask,string req)
        {
            await Task.Run(() => 
            {
                if (waitStartCTUTasks.TryGetValue(batchNumber, out WaitBatchTaskModel info))
                {
                    if (info.subRcsTasks.ContainsKey(taskId))
                    {
                        info.subRcsTasks[taskId] = rcsTask;
                    }
                    else
                    {
                        info.subRcsTasks.Add(taskId, rcsTask);
                    }

                    info.pickGoods.Add(rcsTask,false); 

                    if (info.subTaskReq.ContainsKey(req))
                    {
                        info.subTaskReq[req] = rcsTask;
                    }
                    else
                    {
                        info.subRcsTasks.Add(req, rcsTask);
                    }

                    if (SubTaskCheck(info.subRcsTasks))
                    {
                        info.state = BatchTaskState.allowStart;
                    }
                    waitStartCTUTasks.AddOrUpdate(batchNumber, info, (key, value) => value);
                }
            });
        }
        private async Task AddWaitStartBatchTaskAsync(string batchNumber,string taskId, string seq)
        {
           await Task.Run(() => 
            {
                if (waitStartCTUTasks.TryGetValue(batchNumber,out WaitBatchTaskModel info))
                {
                    if (!info.subRcsTasks.ContainsKey(seq))
                    {
                        info.subRcsTasks.Add(taskId, "");
                        info.subTaskReq.Add(seq, "");
                    }
                    info.state = BatchTaskState.waitStart;
                    waitStartCTUTasks.AddOrUpdate(batchNumber, info, (key, value) => value);
                }
                else
                {
                    WaitBatchTaskModel waitBatchTaskModel = new WaitBatchTaskModel();
                    waitBatchTaskModel.batchNumber = batchNumber;
                    waitBatchTaskModel.subRcsTasks = new Dictionary<string, string>
                    {
                        { taskId,""}
                    };
                    waitBatchTaskModel.subTaskReq = new Dictionary<string, string>
                    {
                        { seq,""}
                    };
                    waitBatchTaskModel.state = BatchTaskState.waitStart;

                    waitStartCTUTasks.AddOrUpdate(batchNumber, waitBatchTaskModel, (key, value) => value);
                }
            });
        }
        /// <summary>
        /// 更新指定批次任务的等待状态
        /// </summary>
        /// <param name="batchNumber"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        private async Task<bool> UpdateWaitStartBatchTaskAsync(string batchNumber, BatchTaskState state)
        {
            return await Task.Run(() => 
            {
                if (!waitStartCTUTasks.TryGetValue(batchNumber,out WaitBatchTaskModel info))
                {
                    Log.Error($"CTU批次任务不存在，批信号{batchNumber}");
                    return false;
                }
                info.state = state;
                waitStartCTUTasks.AddOrUpdate(batchNumber, info, (key, value) => value);
                return true;
            });
        }
        private async Task<bool> RemoveWaitStartBatchTask(string batchNumber)
        {
            return await Task.Run(() => 
            {
                if (waitStartCTUTasks.TryRemove(batchNumber, out WaitBatchTaskModel flag))
                {
                    return true;
                }
                return false;
            });
        }
        /// <summary>
        /// 查询等待任务开始组信息根据rcs任务
        /// </summary>
        /// <param name="rcsTask"></param>
        /// <returns></returns>
        private async Task<(BatchTaskState,string,Dictionary<string,string>)> QueryWaitTaskStateBaseRcstask(string rcsTask)
        {
            return await Task.Run(() => 
            {
                foreach (var item in waitStartCTUTasks)
                {
                    if (item.Value.subRcsTasks is not null)
                    {
                        foreach (var item1 in item.Value.subRcsTasks)
                        {
                            if (item1.Value == rcsTask)
                            {
                                return (item.Value.state,item.Value.batchNumber,item.Value.subTaskReq);
                            }
                        }
                    }
                }
                return (BatchTaskState.unKnow,"",null);
            });
        }
        #endregion

        private string GetreqCode() => Guid.NewGuid().ToByteArray().Aggregate<byte, long>(1, (current, b) => current * (b + 1)).ToString();

        #region 滚筒参数设置
        private RollerWriteModel CreatRollerInfo(RollerWriteState stateUp, RollerWriteState statrDown)
        {
            RollerWriteModel model = new();
            model.rollerUpAction = stateUp;
            model.rollerUpSpeed = rollerParaModel.Speed;
            model.rollerUpAss = rollerParaModel.Ass;
            model.rollerUpDec = rollerParaModel.Dec;
            model.rollerUpLoadStopTime = rollerParaModel.LoadTime;
            model.rollerUpUnloadStopTime = rollerParaModel.UnloadTime;

            model.rollerDownAction = statrDown;
            model.rollerDownSpeed = rollerParaModel.Speed;
            model.rollerDownAss = rollerParaModel.Ass;
            model.rollerDownDec = rollerParaModel.Dec;
            model.rollerDownLoadStopTime = rollerParaModel.LoadTime;
            model.rollerDownUnloadStopTime = rollerParaModel.UnloadTime;
            return model;
        }
        #endregion
    }
}
